﻿// MediaInfo.h: interface for the CMediaInfo class.
//
// GetInfo(LPCTSTR)
//////////////////////////////////////////////////////////////////////

#pragma once

#include "Redirect.h"
#include "SmallUtilz.h"

#define MAXAUDSUBCOUNT 50

enum FileFormat {
	FFMT_NONE,
	FFMT_AVI,
	FFMT_DIVX,
	FFMT_MKV,
	FFMT_FLV,
	FFMT_OGG,
	FFMT_MP4,
	FFMT_MPGPS,
	FFMT_MPGTS,
	FFMT_BLURAY,
	FFMT_WMV,
	FFMT_SWF,
	FFMT_QT,
	FFMT_WEBM,
	FFMT_RM,
	FFMT_UNKNOWN
};

enum AudioFormat {
	AFMT_NONE,
	AFMT_AAC,
	AFMT_DTS,
	AFMT_AC3,
	AFMT_MP3,
	AFMT_OGG,
	AFMT_PCM,
	AFMT_WMA,
	AFMT_FLAC,
	AFMT_TWOS,
	AFMT_RM,
	AFMT_UNKNOWN
};

enum VideoFormat {
	VFMT_NONE,
	VFMT_H264,
	VFMT_MPEG,
	VFMT_MPEG4,
	VFMT_WMV,
	VFMT_VC1,
	VFMT_H263,
	VFMT_MJPEG,
	VFMT_VP6,
	VFMT_VP7,
	VFMT_VP8,
	VFMT_CINEPAK,
	VFMT_RLE,
	VFMT_RM,
	VFMT_UNKNOWN
};

enum SubFormat {
	SFMT_NONE,
	SFMT_SRT,
	SFMT_TTXT,
	SFMT_ASS,
	SFMT_UNKNOWN
};

class CMediaInfo
{
protected:
	CString csMediaInfoExe;
	CString csMediaInfoLongExe;
	CString csFFMpegExe;
	CString csFFMpegLongExe;
	CString csFFMpegResult;
	CString csTempFolder;
	void printfuni2ansi(FILE *f, const TCHAR *tc);
	TCHAR tcFilename[MAX_PATH];
	BOOL bIgnoreUTC;
	
public:
	void initValues();
	bool compareNGetValue(char *cBuf, const char *cName, CString &cs);
	bool base64Decode(LPCTSTR lpStr, LPCTSTR lpFilename);
	bool GetTime(CString &cs, int &iTime);
	void GetValue(CString &cs);
	void GetMediaInfo(LPCTSTR lpFilename, bool processCover, LPCTSTR lpAudioCountry = NULL);
	CMediaInfo();
	CMediaInfo(LPCTSTR lpMediaInfoExe, LPCTSTR lpMediaInfoLongExe, LPCTSTR lpFFMpegExe, LPCTSTR lpFFMpegLongExe, LPCTSTR lpTempFolder, int m_iKeepTempFiles, BOOL m_bIgnoreUTC);
	virtual ~CMediaInfo();
	void initMediaInfo(LPCTSTR lpMediaInfoExe, LPCTSTR lpMediaInfoLongExe, LPCTSTR lpFFMpegExe, LPCTSTR lpFFMpegLongExe, LPCTSTR lpTempFolder, int m_iKeepTempFiles, BOOL m_bIgnoreUTC);
	
	FileFormat ffFileFormat;
	int iFileSizeInMB;
	CStringArray csaExtList;
	
	VideoFormat vfVideoFormat;
	
	CTime fileTime;
	CString csFPS;
	int iVideoID;			// ID (for mp4box)
	int iVideoStreamOrder;	// Streamorder (for FFMpeg)
	int iVideoDelay;
	int iFileDuration;
	int iVideoDuration;
	CString cs264Profile;
	int i264ReferenceFrames;
	int iWidth;
	int iHeight;
	int iRotation;
	int iFrameCount;
	int iOverallBitRate;
	int iVideoBitRate;
	int iVideoMaxBitRate;
	int iBitDepthV;
	int iDIVxMPEG4;
	double dPAR;
	int iMPEG4_BVOP;
	int iMPEG4_QPel;
	int iMPEG4_GMC;
	int iMPEG4_Matrix;
	int iInterlace;
	bool bVFR;
	CString csVideoTitle;
	
	int iAudioCount;
	int iAudioID[MAXAUDSUBCOUNT];			// ID (for mp4box)
	int iAudioStreamOrder[MAXAUDSUBCOUNT];	// StreamOrder
	int iAudioDelay[MAXAUDSUBCOUNT];
	AudioFormat afAudioFormat[MAXAUDSUBCOUNT];
	int iAudioDuration[MAXAUDSUBCOUNT];
	int iBitRate[MAXAUDSUBCOUNT];
	bool bProfileIsLC[MAXAUDSUBCOUNT];
	TCHAR tcAudioLang[MAXAUDSUBCOUNT*3];
	int iAudioWeight[MAXAUDSUBCOUNT];	// 우선순위
	//PCM을 위한 정보들
	int iSamplingRate[MAXAUDSUBCOUNT];
	int iChannels[MAXAUDSUBCOUNT];
	int iBitDepthA[MAXAUDSUBCOUNT];
	CString csAudioTitle[MAXAUDSUBCOUNT];
	
	int iSubCount;
	int iSubCountSbtlOnly;		// MP4 only, 다른 포맷에선 iSubCount 과 동일
	int iSubChapterID;			// MP4 only
	int iChapter;				// 0: 없음, 1: 챕터, 2: TTXT 챕터
	CStringArray csaChapters;	// 000121217챕터이름 포맷
	int iSubID[MAXAUDSUBCOUNT];				// ID (for mp4box)
	int iSubStreamOrder[MAXAUDSUBCOUNT];	// StreamOrder
	bool bMuxingModeSbtl[MAXAUDSUBCOUNT];
	TCHAR tcSubLang[MAXAUDSUBCOUNT*3];
	SubFormat sfSubFormat[MAXAUDSUBCOUNT];
	int iSubDelay[MAXAUDSUBCOUNT];
	CString csSubTitle[MAXAUDSUBCOUNT];

	int iMenuStreamOrder;
	SubFormat sfMenuFormat;
	int iMenuID;
	
	CString csCover;
	
	long long llVideoSize;
	long long llAudioSize;
	//void PrintfInfo(LPCTSTR lpFilename);

	int iKeepTempFiles;

protected:
	inline int iscntrl_char(char c) { return __isascii(c) && iscntrl(c); }
	inline int isspace_char(char c) { return __isascii(c) && isspace(c); }
	inline int isdigit_char(char c) { return __isascii(c) && isdigit(c); }

public:
	void getDefaultAudioExt(AudioFormat af, LPCTSTR &lpExt);
	void getAudioType(AudioFormat af, LPCTSTR &lpType);
	void getDefaultContainerType(FileFormat ff, LPCTSTR &lpType);
	void fixTitle(CString &cs);
};
